﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;

namespace ConsoleApplication1
{
    class Program
    {
        private static Feeder[] Client = new Feeder[999];
        private static int ctr = 0;
        private static String key = "c";
        private static int line1 = 1; int line2 = 2;
        private static string[] lines = new String[999];
        private static string[] lines2 = new String[999];
        static void Main(string[] args)
        {
            TcpListener server = new TcpListener(23);
            server.Start();
            Console.Title = "Group 4 Project Server";
            Console.WriteLine("Server Started...");
            while (true) { 
                TcpClient tc = server.AcceptTcpClient();
                Thread clientstart = new Thread(new ParameterizedThreadStart(AcceptClient));
                clientstart.Start(new CDeatail(ctr++, tc));

            }
        }
        public static  void AcceptClient(object x){
            try
            {
                TcpClient tc;
                int index;
                if (x is CDeatail)
                {
                    tc = ((CDeatail)x).tc;
                    index = ((CDeatail)x).indexer;
                    if (tc == null)
                        return;
                }
                else
                    return;

                StreamReader reader = new StreamReader(tc.GetStream());
                StreamWriter writer = new StreamWriter(tc.GetStream());
                String cmd = "";
                bool running = true;
                while (running)
                {
                    String[] cmnd;
                    cmd = reader.ReadLine();
                    if (cmd == null || cmd.Length == 0)
                        continue;

                        
                        

                    lines[line1] += ("Encrypted:" + cmd);
                    Console.WriteLine("Encrypted:" + cmd);
                    cmd = Crypt.Decrypt(cmd, key);
                    lines2[line1] += ("Decrypted:" + cmd); 
                    Console.WriteLine("Decrypted:"+ cmd);
                    // WriteAllLines creates a file, writes a collection of strings to the file, 
                    // and then closes the file.
                    System.IO.File.WriteAllLines(@"C:\Encrypted.txt", lines);
                    System.IO.File.WriteAllLines(@"C:\Decrypted.txt", lines2);
                    if ((cmnd = cmd.Split(' ')).Length < 2)
                        continue;
                    switch (cmnd[0])
                    {
                        case "Connect":
                            string ol = "";
                            Client[index] = new Feeder();
                            Client[index].Status = "Online";
                            Client[index].ClientName = cmnd[1];
                            Client[index].ClientIP = ((IPEndPoint)tc.Client.RemoteEndPoint).Address.ToString();
                            Client[index].tc = tc;
                            Console.WriteLine("Connected from {1} named:{0}\n", Client[index].ClientName, Client[index].ClientIP);
                            UpdateAllUser();
                            break;
                        case "Send":
                            String ip = cmnd[1];
                            String name = cmnd[2];
                            String mes = cmd.Replace("Send " + ip + " " + name + " ", "");
                            foreach (Feeder xl in Client)
                            {
                                if (xl.Status == "Online" && xl.ClientIP.Equals(ip) && xl.ClientName.Equals(name))
                                {
                                    StreamWriter ase = new StreamWriter(xl.tc.GetStream());
                                    ase.WriteLine(Crypt.Encrypt("Receive " + Client[index].ClientName + ": " + mes, key));
                                    ase.Flush();
                                    break;
                                }
                            }
                            break;
                        case "Disconnect":
                            Client[index].Status = "Offline";
                            running = false;
                            Console.WriteLine("{0} is disconnecting.\n", Client[index].ClientName);
                            UpdateAllUser();
                            return;
                    }
                    line1 ++;
                }
                reader.Close();
                writer.Close();
                tc.Close();
            }
            catch (Exception e) { };
        }
        public static void UpdateAllUser()
        {
            foreach (Feeder xl in Client)
            {
                if (xl != null && xl.Status == "Online")
                {
                    String ol = "";
                    StreamWriter ase = new StreamWriter(xl.tc.GetStream());
                    foreach (Feeder xls in Client)
                    {
                        if (xls != null && xls.Status == "Online" && !xls.ClientName.Equals(xl.ClientName))
                        {
                            ol += xls.ClientName + ":" + xls.ClientIP + "|";
                        }
                    }
                    ase.WriteLine(Crypt.Encrypt("Users " + ol, key));
                    ase.Flush();
                }
            }
        }
    }
    class CDeatail
    {
        public int indexer;
        public TcpClient tc;
        public CDeatail(int indexer, TcpClient tc)
        {
            this.indexer = indexer;
            this.tc = tc;
        }
    }
    class Feeder {
        public String ClientName;
        public String ClientIP;
        public TcpClient tc;
        public String Status;
            public Feeder(){
        }
    }
}
